#ifndef POLYGON_H
#define POLYGON_H

#pragma warning(disable:4251)

#include "Triangle.h"
#include "Objects.h"
#include "Primitive.h"

#include "Ray.h"

#include <vector>

/**
 * Un polygone, constitué d'une série de triangles
 */
class OBJECT_API Polygon : public Primitive{
	public:
		/**
		* Un polygone n'est qu'un ensemble de triangles
		*
		* les intersections calculées le sont donc au niveau individuel
		* des triangles
		*/
    
		/**
		* Creer un polygone vide
		*/
		Polygon();

		/**
		* Destructeur
		*/
		virtual ~Polygon();

		/**
		* Rajoute un triangle
		* @param t Le triangle à ajouter
		*/
		void addTriangle(Math::Triangle t);
    
		/**
		* Intersection entre un rayon et le polygone
		* @param ray Le rayon à tester
		* @param distance référence à un float qui est la distance minimale
		* @param second Si le rayon est un rayon secondaire
		* @return Vrai si le rayon intersecte la sphère
		**/
		bool intersects(Math::Ray &ray, float &distance, bool second);

		/**
		* Intersection entre le polygone en un plan
		* @param plane Le plane à tester
		* @param distance Référence à un float qui est la distance minimale
		* @return OUTSIDE si l'objet est derrière le plane, INTERSECTS si 
		* l'objet intersecte le plan et INSIDE si l'objet est devant l'objet
		*/
		int intersects(Math::Plane &plane, float &distance);

		/**
		* Calcul les constantes pour la caméra
		* @pos Position de la caméra
		*/
		virtual void calculatesConstants(Math::Vector &pos);

		/**
		* Retourne la normale et l'UV du point d'intersection
		* si les parametres sont non-nuls
		* @param ray Le rayon avec lequel il y a eu intersection
		* @param t La distance entre la caméra et le point d'intersection
		* @param normal Pointeur à un vecteur pour retourner la normal de surface
		* du point d'intersection
		* @param uv Pointeur à un vecteur pour retourner les coordonées uv au point
		* d'intersection
		*/
		void getIntersectionParams(Math::Ray &ray,const float t, Math::Vector *normal, Math::Vector *uv);

		/**
		* Retourne le point minimum et le point maximum de l'objet
		* (pour le calcul des BondingVolume)
		* @param min Une référence à un vector
		* @param max Une référence à un vector
		*/
		virtual void getMinMax(Math::Vector &min, Math::Vector &max) {}
        
        /**
         * Recalcule les normales des triangles pour permettre une interpolation linéaire
         */
        void smooth();
        
	private:
		std::vector<Math::Triangle> m_Triangles;		///< Vecteur de triangles du polygon

}; // Class

#endif
